/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package aspect.editor;
import aspect.editor.LevelEditor.Tool;
import aspect.resources.Resources;
import aspect.util.Color;
import aspect.util.Vector2;
import aspect.util.Vector3;
import java.awt.BasicStroke;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import org.lwjgl.opengl.Display;
/**
*
* @author vincent
*/
public class View2D extends javax.swing.JPanel {
private BufferedImage image;
private Graphics2D pen;
public Axes axes;
public EditorControl control;
public LevelEditor editor;
private DragPoint currentPoint;
private Point lastMouse;
/**
* Creates new form View2D
*/
public View2D() {
initComponents();
MouseAdapter mouse = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent evt) {
if (editor.currentTool() == Tool.BLOCK) {
CubeBuilder builder = control.builder;
builder.min = getPointInWorld(snap(evt.getPoint()));
EditorBlock block = getSelectedBlock();
if (block != null) {
builder.min = axes.copyUnknown(block.min, builder.min);
}
builder.max = builder.min.copy();
} else {
currentPoint = getDragPoint(evt.getPoint());
}
lastMouse = evt.getPoint();
}
@Override
public void mouseReleased(MouseEvent evt) {
if (editor.currentTool() == Tool.BLOCK) {
CubeBuilder builder = control.builder;
if (builder.min.x > builder.max.x) {
float t = builder.min.x;
builder.min.x = builder.max.x;
builder.max.x = t;
}
if (builder.min.y > builder.max.y) {
float t = builder.min.y;
builder.min.y = builder.max.y;
builder.max.y = t;
}
if (builder.min.z > builder.max.z) {
float t = builder.min.z;
builder.min.z = builder.max.z;
builder.max.z = t;
}
}
}
@Override
public void mouseDragged(MouseEvent evt) {
EditorBlock block = getSelectedBlock();
if (editor.currentTool() == Tool.BLOCK) {
CubeBuilder builder = control.builder;
builder.max = getPointInWorld(snap(evt.getPoint()));
if (block != null) {
builder.max = axes.copyUnknown(block.max, builder.max);
}
} else if (currentPoint != null) {
int xmin = (evt.getX() - lastMouse.x) * currentPoint.xmin;
int ymin = (evt.getY() - lastMouse.y) * currentPoint.ymin;
int xmax = (evt.getX() - lastMouse.x) * currentPoint.xmax;
int ymax = (evt.getY() - lastMouse.y) * currentPoint.ymax;
//System.out.println("minx: " + xmin + ", miny: " + ymin + ", maxx + " + xmax + ", maxy: " + ymax);
getSelectedBlock();
Dimension minAdd = snap(new Dimension(xmin, ymin));
Dimension maxAdd = snap(new Dimension(xmax, ymax));
block.min = block.min.plus(getSizeInWorld(minAdd));
block.max = block.max.plus(getSizeInWorld(maxAdd));
if (minAdd.width != 0 || maxAdd.width != 0) {
lastMouse.x = evt.getX();
}
if (minAdd.height != 0 || maxAdd.height != 0) {
lastMouse.y = evt.getY();
}
block.valid = false;
}
}
};
addMouseListener(mouse);
addMouseMotionListener(mouse);
}
private EditorBlock getSelectedBlock() {
return (EditorBlock) editor.getEntityList().getSelectedValue();
}
private DragPoint getDragPoint(Point point) {
EditorBlock block = getSelectedBlock();
if (block == null) {
return null;
}
Point center = getPointInView(block.position());
Dimension size = getSizeInView(block.size());
for (int x = -1; x < 2; x++) {
for (int y = -1; y < 2; y++) {
Point dragPoint = new Point(center.x + x * size.width / 2, center.y + y * size.height / 2);
if (point.distance(dragPoint) < 4) {
return new DragPoint(x, y);
}
}
}
return null;
}
public void drawBlock(Drawable2D block) {
Point min = getPointInView(block.min());
Point max = getPointInView(block.max());
Point realMin = new Point();
Point realMax = new Point();
realMin.x = Math.min(min.x, max.x);
realMax.x = Math.max(min.x, max.x);
realMin.y = Math.max(min.y, max.y);
realMax.y = Math.min(min.y, max.y);
pen.setColor(block.color().toAWT());
pen.setStroke(new BasicStroke(2));
pen.drawRect(realMin.x, realMax.y, realMax.x - realMin.x, realMin.y - realMax.y);
pen.setStroke(new BasicStroke(1));
if (editor.getEntityList().getSelectedValue() == block) {
drawDragPoints(realMin, realMax);
}
}
private void drawDragPoints(Point min, Point max) {
Point center = new Point((min.x + max.x) / 2, (min.y + max.y) / 2);
Dimension size = new Dimension(max.x - min.x, min.y - max.y);
for (int x = -1; x < 2; x++) {
for (int y = -1; y < 2; y++) {
drawDragPoint(center.x + x * size.width / 2, center.y + y * size.height / 2);
}
}
}
private void drawDragPoint(int x, int y) {
pen.fillRect(x - 3, y - 3, 6, 6);
}
@Override
public void paintComponent(Graphics g) {
if (image != null) {
g.drawImage(image, 0, 0, this);
}
}
public void clear(Color color) {
pen.setColor(color.toAWT());
pen.fillRect(0, 0, getWidth(), getHeight());
}
public Graphics2D getPen() {
return pen;
}
public void setupDraw() {
clear(Color.BLACK);
drawGrid();
pen.setColor(Color.RED.toAWT());
pen.drawString(axes.name() + " View", 15, 20);
}
public void drawGrid() {
pen.setStroke(new BasicStroke(1));
pen.setColor(new Color(0.5f, 0.5f, 0.5f).toAWT());
int numx = (int) scaleToWorld(getWidth());
int numy = (int) scaleToWorld(getHeight());
for (int i = -numx / 2; i <= numx / 2; i++) {
int x = centerX() + scaleToView(i);
pen.drawLine(x, 0, x, getHeight());
}
for (int j = numy / 2; j >= -numy / 2; j--) {
int y = centerY() + scaleToView(j);
pen.drawLine(0, y, getWidth(), y);
}
pen.setColor(Color.WHITE.toAWT());
pen.drawLine(centerX(), 0, centerX(), getHeight());
pen.drawLine(0, centerY(), getWidth(), centerY());
}
private class DragPoint {
private int xmin;
private int ymin;
private int xmax;
private int ymax;
private DragPoint(int x, int y) {
this.xmin = x == -1 ? 1 : 0;
this.ymin = y == 1 ? -1 : 0;
this.xmax = x == 1 ? 1 : 0;
this.ymax = y == -1 ? -1 : 0;
if (x == 0 && y == 0) {
xmin = 1;
ymin = -1;
xmax = 1;
ymax = -1;
}
}
}
public enum Axes {
XY {
@Override
public Vector2 toView(Vector3 point) {
return point.xy();
}
@Override
public Vector3 toWorld(Vector2 point) {
return point.asXY();
}
@Override
public Vector3 copyUnknown(Vector3 source, Vector3 dest) {
return new Vector3(dest.x, dest.y, source.z);
}
},
ZY {
@Override
public Vector2 toView(Vector3 point) {
return point.zy();
}
@Override
public Vector3 toWorld(Vector2 point) {
return point.asZY();
}
@Override
public Vector3 copyUnknown(Vector3 source, Vector3 dest) {
return new Vector3(source.x, dest.y, dest.z);
}
},
XZ {
@Override
public Vector2 toView(Vector3 point) {
return point.xz();
}
@Override
public Vector3 toWorld(Vector2 point) {
return point.asXZ();
}
@Override
public Vector3 copyUnknown(Vector3 source, Vector3 dest) {
return new Vector3(dest.x, source.y, dest.z);
}
};
public abstract Vector3 toWorld(Vector2 point);
public abstract Vector2 toView(Vector3 point);
public abstract Vector3 copyUnknown(Vector3 source, Vector3 dest);
}
public Point snap(Point point) {
int x = ((int) Math.round((point.x - centerX()) / 16.0f)) * 16 + centerX();
int y = ((int) Math.round((point.y - centerY()) / 16.0f)) * 16 + centerY();
return new Point(x, y);
}
public Dimension snap(Dimension dim) {
int width = ((int) Math.round(dim.width / 16.0f)) * 16;
int height = ((int) Math.round(dim.height / 16.0f)) * 16;
return new Dimension(width, height);
}
public Point getPointInView(Vector3 point) {
Vector2 usedAxes = axes.toView(point);
int x = centerX() + scaleToView(usedAxes.x);
int y = centerY() - scaleToView(usedAxes.y);
return new Point(x, y);
}
public Vector3 getPointInWorld(Point point) {
float x = scaleToWorld(point.x - centerX());
float y = -scaleToWorld(point.y - centerY());
Vector2 usedAxes = new Vector2(x, y);
return axes.toWorld(usedAxes);
}
public Dimension getSizeInView(Vector3 size) {
Vector2 usedAxes = axes.toView(size);
int x = scaleToView(usedAxes.x);
int y = scaleToView(usedAxes.y);
return new Dimension(x, y);
}
public Vector3 getSizeInWorld(Dimension size) {
float x = scaleToWorld(size.width);
float y = scaleToWorld(size.height);
Vector2 usedAxes = new Vector2(x, y);
return axes.toWorld(usedAxes);
}
public int centerX() {
return getWidth() / 2;
}
public int centerY() {
return getHeight() / 2;
}
public int scaleToView(float world) {
return (int) (world * 16);
}
public float scaleToWorld(int view) {
return view / 16f;
}
@Override
public void setCursor(Cursor c) {
System.out.println("Cursor set in " + axes.name());
super.setCursor(c);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentResized(java.awt.event.ComponentEvent evt) {
formComponentResized(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents
private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
image = Resources.createImage(getWidth(), getHeight());
pen = image.createGraphics();
}//GEN-LAST:event_formComponentResized
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
}